﻿using System.Collections.ObjectModel;

using TrivialPurfuit.Data;

namespace TrivialPurfuit.Business
{
    class GameBoard : BindableObject
    {

        ///////////////////////////////////////////////////////////////////////////////////////////
        // Singleton stuff
        ///////////////////////////////////////////////////////////////////////////////////////////
        /// <summary>
        /// This is a singleton class, this is the static instance of this class.
        /// </summary>
        private static GameBoard _Instance;

        /// <summary>
        /// Gets the singleton instance of the GameBoard class.
        /// </summary>
        /// <returns>Singleton instance of the GameBoard class</returns>
        public static GameBoard Instance
        {
            get
            {
                if (GameBoard._Instance == null)
                    _Instance = new GameBoard();

                return GameBoard._Instance;
            }
        }

        /// <summary>
        /// Private constructor to get things setup and to prevent instanciation else where.
        /// </summary>
        private GameBoard()
        {
            // This needs to be the order Catagories, spaces then pieces.
            InstanciateCatagories();
            InstanciateSpaces();
            PutSpacesInArray();
            InstanciatePieces();

            this._ShowAnswer = false;
            this._ShowQuestion = false;
            this._EnableDieButton = false;
            this._EnableAnswerButton = false;
            this._EnableVerifyButtons = false;

            _Die = null;
        }


        ///////////////////////////////////////////////////////////////////////////////////////////
        // Components of the game
        ///////////////////////////////////////////////////////////////////////////////////////////

        private int? _Die;
        public int? Die 
        {
            get 
            { 
                return _Die; 
            }

            set 
            {
                _Die = value;
                this.RaisePropertyChanged("Die");
            }
        }

        public QuestionCategory NullCategory { get; set; }

        private QuestionCategory _Category1; 
        public QuestionCategory Category1 
        {
            get
            {
                return _Category1;
            }
            set
            {
                _Category1.changeWithoutReplacing(value);
            }
        }

        private QuestionCategory _Category2;
        public QuestionCategory Category2
        {
            get
            {
                return _Category2;
            }
            set
            {
                _Category2.changeWithoutReplacing(value);
            }
        }

        private QuestionCategory _Category3;
        public QuestionCategory Category3
        {
            get
            {
                return _Category3;
            }
            set
            {
                _Category3.changeWithoutReplacing(value);
            }
        }

        private QuestionCategory _Category4;
        public QuestionCategory Category4
        {
            get
            {
                return _Category4;
            }
            set
            {
                _Category4.changeWithoutReplacing(value);
            }
        }


        private QuestionCard _QuestionCard;
        public QuestionCard QuestionCard
        {
            get
            {
                return _QuestionCard;
            }
            set
            {
                _QuestionCard = value;
                this.RaisePropertyChanged("Question");
                this.RaisePropertyChanged("Answer");
                this.RaisePropertyChanged("QuestionCategoryName");
            }
        }

        public string QuestionCategoryName
        {
            get
            {
                if (_QuestionCard == null)
                    return "";
                else
                    return _QuestionCard.CategoryName;
            }
        }

        public string Question
        {
            get
            {
                if (_QuestionCard == null)
                    return "";
                else
                    return _QuestionCard.Question;
            }
        }

        public string Answer
        {
            get
            {
                if (_QuestionCard == null)
                    return "";
                else
                    return _QuestionCard.Answer;
            }
        }

        private bool _ShowAnswer;
        public bool ShowAnswer
        {
            get
            {
                return _ShowAnswer;
            }
            set
            {
                _ShowAnswer = value;
                this.RaisePropertyChanged("ShowAnswer");
            }
        }

        private bool _ShowQuestion;
        public bool ShowQuestion
        {
            get
            {
                return _ShowQuestion;
            }
            set
            {
                _ShowQuestion = value;
                this.RaisePropertyChanged("ShowQuestion");
            }
        }

        private bool _EnableDieButton;
        public bool EnableDieButton
        {
            get
            {
                return _EnableDieButton;
            }
            set
            {
                _EnableDieButton = value;
                this.RaisePropertyChanged("EnableDieButton");
            }
        }

        private bool _EnableAnswerButton;
        public bool EnableAnswerButton
        {
            get
            {
                return _EnableAnswerButton;
            }
            set
            {
                _EnableAnswerButton = value;
                this.RaisePropertyChanged("EnableAnswerButton");
            }
        }

        private bool _EnableVerifyButtons;
        public bool EnableVerifyButtons
        {
            get
            {
                return _EnableVerifyButtons;
            }
            set
            {
                _EnableVerifyButtons = value;
                this.RaisePropertyChanged("EnableVerifyButtons");
            }
        }

        public GamePiece Piece1 { get; private set; }
        public GamePiece Piece2 { get; private set; }
        public GamePiece Piece3 { get; private set; }
        public GamePiece Piece4 { get; private set; }

        public ObservableCollection<GamePiece> Pieces { get; private set; }
        public ObservableCollection<GameSpace> Spaces { get; private set; }

        public GameSpace Space00 { get; private set; }
        public GameSpace Space01 { get; private set; }
        public GameSpace Space02 { get; private set; }
        public GameSpace Space03 { get; private set; }
        public GameSpace Space04 { get; private set; }
        public GameSpace Space05 { get; private set; }
        public GameSpace Space06 { get; private set; }
        public GameSpace Space07 { get; private set; }
        public GameSpace Space08 { get; private set; }
        public GameSpace Space09 { get; private set; }

        public GameSpace Space10 { get; private set; }
        public GameSpace Space11 { get; private set; }
        public GameSpace Space12 { get; private set; }
        public GameSpace Space13 { get; private set; }
        public GameSpace Space14 { get; private set; }
        public GameSpace Space15 { get; private set; }
        public GameSpace Space16 { get; private set; }
        public GameSpace Space17 { get; private set; }
        public GameSpace Space18 { get; private set; }
        public GameSpace Space19 { get; private set; }

        public GameSpace Space20 { get; private set; }
        public GameSpace Space21 { get; private set; }
        public GameSpace Space22 { get; private set; }
        public GameSpace Space23 { get; private set; }
        public GameSpace Space24 { get; private set; }
        public GameSpace Space25 { get; private set; }
        public GameSpace Space26 { get; private set; }
        public GameSpace Space27 { get; private set; }
        public GameSpace Space28 { get; private set; }
        public GameSpace Space29 { get; private set; }

        public GameSpace Space30 { get; private set; }
        public GameSpace Space31 { get; private set; }
        public GameSpace Space32 { get; private set; }
        public GameSpace Space33 { get; private set; }
        public GameSpace Space34 { get; private set; }
        public GameSpace Space35 { get; private set; }
        public GameSpace Space36 { get; private set; }
        public GameSpace Space37 { get; private set; }
        public GameSpace Space38 { get; private set; }
        public GameSpace Space39 { get; private set; }

        public GameSpace Space40 { get; private set; }
        public GameSpace Space41 { get; private set; }
        public GameSpace Space42 { get; private set; }
        public GameSpace Space43 { get; private set; }
        public GameSpace Space44 { get; private set; }
        public GameSpace Space45 { get; private set; }
        public GameSpace Space46 { get; private set; }
        public GameSpace Space47 { get; private set; }
        public GameSpace Space48 { get; private set; }
        public GameSpace Space49 { get; private set; }

        public GameSpace Space50 { get; private set; }
        public GameSpace Space51 { get; private set; }
        public GameSpace Space52 { get; private set; }
        public GameSpace Space53 { get; private set; }
        public GameSpace Space54 { get; private set; }
        public GameSpace Space55 { get; private set; }
        public GameSpace Space56 { get; private set; }


        public void determineWhichPiecesAreUsed()
        {
            this.Pieces.Clear();

            if(Piece1.PlayerName.Length > 0)
                this.Pieces.Add(Piece1);

            if (Piece2.PlayerName.Length > 0)
                this.Pieces.Add(Piece2);

            if (Piece3.PlayerName.Length > 0)
                this.Pieces.Add(Piece3);

            if (Piece4.PlayerName.Length > 0)
                this.Pieces.Add(Piece4);
        }


        ///////////////////////////////////////////////////////////////////////////////////////////
        // Private functions
        ///////////////////////////////////////////////////////////////////////////////////////////
        private void InstanciateCatagories()
        {
            this.NullCategory = new QuestionCategory(QuestionData.Instance.Catagory.FindByid(CategoryCON.NULL.ID));
            this._Category1 = new QuestionCategory(QuestionData.Instance.Catagory.FindByid(1));
            this._Category2 = new QuestionCategory(QuestionData.Instance.Catagory.FindByid(2));
            this._Category3 = new QuestionCategory(QuestionData.Instance.Catagory.FindByid(3));
            this._Category4 = new QuestionCategory(QuestionData.Instance.Catagory.FindByid(4));

        }

        private void InstanciateSpaces()
        {
            // Top Row
            this.Space00 = new GameSpace(0, 100, 25, 25, this.Category1);
            this.Space01 = new GameSpace(1, 50, 135, 50, this.Category3);
            this.Space02 = new GameSpace(2, 50, 195, 50, this.Category4);
            this.Space03 = new GameSpace(3, 50, 255, 50, this.Category1);
            this.Space04 = new GameSpace(4, 50, 315, 50, this.NullCategory);
            this.Space05 = new GameSpace(5, 50, 375, 50, this.Category2);
            this.Space06 = new GameSpace(6, 50, 435, 50, this.NullCategory);
            this.Space07 = new GameSpace(7, 50, 495, 50, this.Category3);
            this.Space08 = new GameSpace(8, 50, 555, 50, this.Category4);
            this.Space09 = new GameSpace(9, 50, 615, 50, this.Category1);
            this.Space10 = new GameSpace(10, 100, 675, 25, this.Category2);

            // Right Column Not including base squares
            this.Space11 = new GameSpace(11, 50, 700, 135, this.Category4);
            this.Space12 = new GameSpace(12, 50, 700, 195, this.Category1);
            this.Space13 = new GameSpace(13, 50, 700, 255, this.Category2);
            this.Space14 = new GameSpace(14, 50, 700, 315, this.NullCategory);
            this.Space15 = new GameSpace(15, 50, 700, 375, this.Category3);
            this.Space16 = new GameSpace(16, 50, 700, 435, this.NullCategory);
            this.Space17 = new GameSpace(17, 50, 700, 495, this.Category4);
            this.Space18 = new GameSpace(18, 50, 700, 555, this.Category1);
            this.Space19 = new GameSpace(19, 50, 700, 615, this.Category2);

            // Bottom Row
            this.Space20 = new GameSpace(20, 100, 675, 675, this.Category3);
            this.Space21 = new GameSpace(21, 50, 615, 700, this.Category1);
            this.Space22 = new GameSpace(22, 50, 555, 700, this.Category2);
            this.Space23 = new GameSpace(23, 50, 495, 700, this.Category3);
            this.Space24 = new GameSpace(24, 50, 435, 700, this.NullCategory);
            this.Space25 = new GameSpace(25, 50, 375, 700, this.Category4);
            this.Space26 = new GameSpace(26, 50, 315, 700, this.NullCategory);
            this.Space27 = new GameSpace(27, 50, 255, 700, this.Category1);
            this.Space28 = new GameSpace(28, 50, 195, 700, this.Category2);
            this.Space29 = new GameSpace(29, 50, 135, 700, this.Category3);
            this.Space30 = new GameSpace(30, 100, 25, 675, this.Category4);

            // Left Column Not including base squares
            this.Space31 = new GameSpace(31, 50, 50, 615, this.Category2);
            this.Space32 = new GameSpace(32, 50, 50, 555, this.Category3);
            this.Space33 = new GameSpace(33, 50, 50, 495, this.Category4);
            this.Space34 = new GameSpace(34, 50, 50, 435, this.NullCategory);
            this.Space35 = new GameSpace(35, 50, 50, 375, this.Category1);
            this.Space36 = new GameSpace(36, 50, 50, 315, this.NullCategory);
            this.Space37 = new GameSpace(37, 50, 50, 255, this.Category2);
            this.Space38 = new GameSpace(38, 50, 50, 195, this.Category3);
            this.Space39 = new GameSpace(39, 50, 50, 135, this.Category4);

            // Top Spoke going into to the middle
            this.Space40 = new GameSpace(40, 50, 375, 110, this.Category3);
            this.Space41 = new GameSpace(41, 50, 375, 170, this.Category4);
            this.Space42 = new GameSpace(42, 50, 375, 230, this.Category1);
            this.Space43 = new GameSpace(43, 50, 375, 290, this.Category2);

            // Right Spoke going into to the middle
            this.Space44 = new GameSpace(44, 50, 640, 375, this.Category4);
            this.Space45 = new GameSpace(45, 50, 580, 375, this.Category1);
            this.Space46 = new GameSpace(46, 50, 520, 375, this.Category2);
            this.Space47 = new GameSpace(47, 50, 460, 375, this.Category3);

            // Bottom Spoke going into to the middle
            this.Space48 = new GameSpace(48, 50, 375, 640, this.Category1);
            this.Space49 = new GameSpace(49, 50, 375, 580, this.Category2);
            this.Space50 = new GameSpace(50, 50, 375, 520, this.Category3);
            this.Space51 = new GameSpace(51, 50, 375, 460, this.Category4);

            // Left Spoke going into to the middle
            this.Space52 = new GameSpace(52, 50, 110, 375, this.Category2);
            this.Space53 = new GameSpace(53, 50, 170, 375, this.Category3);
            this.Space54 = new GameSpace(54, 50, 230, 375, this.Category4);
            this.Space55 = new GameSpace(55, 50, 290, 375, this.Category1);

            // Center Circle
            this.Space56 = new GameSpace(56, 100, 350, 350, this.NullCategory);
        }

        private void PutSpacesInArray()
        {
            this.Spaces = new ObservableCollection<GameSpace>();

            this.Spaces.Add(Space00);
            this.Spaces.Add(Space01);
            this.Spaces.Add(Space02);
            this.Spaces.Add(Space03);
            this.Spaces.Add(Space04);
            this.Spaces.Add(Space05);
            this.Spaces.Add(Space06);
            this.Spaces.Add(Space07);
            this.Spaces.Add(Space08);
            this.Spaces.Add(Space09);


            this.Spaces.Add(Space10);
            this.Spaces.Add(Space11);
            this.Spaces.Add(Space12);
            this.Spaces.Add(Space13);
            this.Spaces.Add(Space14);
            this.Spaces.Add(Space15);
            this.Spaces.Add(Space16);
            this.Spaces.Add(Space17);
            this.Spaces.Add(Space18);
            this.Spaces.Add(Space19);

            this.Spaces.Add(Space20);
            this.Spaces.Add(Space21);
            this.Spaces.Add(Space22);
            this.Spaces.Add(Space23);
            this.Spaces.Add(Space24);
            this.Spaces.Add(Space25);
            this.Spaces.Add(Space26);
            this.Spaces.Add(Space27);
            this.Spaces.Add(Space28);
            this.Spaces.Add(Space29);

            this.Spaces.Add(Space30);
            this.Spaces.Add(Space31);
            this.Spaces.Add(Space32);
            this.Spaces.Add(Space33);
            this.Spaces.Add(Space34);
            this.Spaces.Add(Space35);
            this.Spaces.Add(Space36);
            this.Spaces.Add(Space37);
            this.Spaces.Add(Space38);
            this.Spaces.Add(Space39);

            this.Spaces.Add(Space40);
            this.Spaces.Add(Space41);
            this.Spaces.Add(Space42);
            this.Spaces.Add(Space43);
            this.Spaces.Add(Space44);
            this.Spaces.Add(Space45);
            this.Spaces.Add(Space46);
            this.Spaces.Add(Space47);
            this.Spaces.Add(Space48);
            this.Spaces.Add(Space49);

            this.Spaces.Add(Space50);
            this.Spaces.Add(Space51);
            this.Spaces.Add(Space52);
            this.Spaces.Add(Space53);
            this.Spaces.Add(Space54);
            this.Spaces.Add(Space55);
            this.Spaces.Add(Space56);
        }

        private void InstanciatePieces()
        {
            this.Piece1 = new GamePiece("", Category1.Color);
            this.Piece2 = new GamePiece("", Category2.Color);
            this.Piece3 = new GamePiece("", Category3.Color);
            this.Piece4 = new GamePiece("", Category4.Color);

            this.Pieces = new ObservableCollection<GamePiece>();
        }


    }
}
